<template>
  <el-dialog :title="`${form.patPlanId ? '修改' : '添加'}巡更计划`" :visible.sync="show" :close-on-click-modal="false" :show-close="!btnLoading" width="800px" @closed="closed">
    <el-form ref="form" :model="form" :rules="rules" label-width="100px">
      <el-form-item prop="projectId" class="hide" />
      <el-form-item prop="patPlanId" class="hide" />
      <el-row :gutter="10">
        <el-col :span="24">
          <el-form-item label="巡更类型" prop="patrolTypeId" style="height: 36px">
            <span slot="label">
              巡更类型
              <el-tooltip placement="top" content="更改巡更类型将会清除点位列表">
                <i class="el-icon-warning-outline" />
              </el-tooltip>
            </span>
            <treeselect
              v-model="form.patrolTypeId"
              :options="patTypeTree"
              :normalizer="patTypeNormalizer"
              disable-branch-nodes
              show-count
              placeholder="请选择巡更类型"
              :disabled="isEdit"
              @select="onChangePatrolTypeId"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="10">
        <el-col :span="12">
          <el-form-item label="计划名称" prop="planName"><el-input v-model.trim="form.planName" placeholder="请输入计划名称" :maxlength="100" :disabled="patCfgLoading" /></el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="计划类型" prop="planType">
            <el-select v-model="form.planType" placeholder="请选择计划类型" style="width: 100%" @change="changePlanType">
              <el-option v-for="dict in dict.type.cq_patrol_plan_type" :key="dict.value" :label="dict.label" :value="dict.value" />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="10">
        <el-col :span="12" v-if="showCycleType">
          <el-form-item label="重复次数" prop="cycleType" required key="cycleType">
            <div style="display: flex" :class="{ disabled: patCfgLoading }">
              <div class="el-input-group el-input-group--prepend el-input-group--append" style="flex: 3">
                <div class="el-input-group__prepend" style="padding: 0 10px">每</div>
                <el-input-number v-model="form.cycleCount" :min="1" :max="1e8" :precision="0" :controls="false" style="width: 100%" />
                <div class="el-input-group__append">
                  <el-select v-model="form.cycleType" placeholder="日" style="width: 60px" :disabled="patCfgLoading">
                    <el-option v-for="item in cycleTypeList" :key="item.value" :label="item.label" :value="item.value" />
                  </el-select>
                </div>
              </div>
              <div class="el-input-group el-input-group--append" style="flex: 2; margin-left: 10px">
                <el-input-number v-model="form.times" :min="1" :max="1e8" :precision="0" :controls="false" style="width: 100%" />
                <div class="el-input-group__append" style="padding: 0 10px">次</div>
              </div>
            </div>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="showCycleType">
          <el-form-item label="完成任务天数" prop="daysCounts" key="daysCounts">
            <div class="el-input-group el-input-group--append">
              <el-input-number v-model="form.daysCounts" :min="1" :max="1e8" :precision="0" :controls="false" style="width: 100%" :disabled="patCfgLoading" />
              <div class="el-input-group__append">天</div>
            </div>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="计划开始时间" prop="planBeginDate">
            <el-date-picker v-model="form.planBeginDate" type="datetime" placeholder="选择时间" value-format="yyyy-MM-dd HH:mm:ss" :clearable="false" style="width: 100%" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="计划结束时间" prop="planEndDate" :required="isOnce">
            <el-date-picker v-model="form.planEndDate" type="datetime" placeholder="选择时间" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item label="备注" prop="remark"><el-input v-model="form.remark" type="textarea" placeholder="请输入内容" :maxlength="255" /></el-form-item>
    </el-form>

    <EditSpot ref="EditSpot" :patrol-type-id="form.patrolTypeId" />

    <div slot="footer">
      <el-button type="primary" :loading="btnLoading" @click="btnSubmit">确 定</el-button>
      <el-button :disabled="btnLoading" @click="show = false">取 消</el-button>
    </div>
  </el-dialog>
</template>
<script>
// 添加或修改巡更计划
import moment from 'moment'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { nameRule } from '@/utils/validate'
import { flatList2tree } from '@/utils'
import { editFormMixin } from '@/utils/mixin'
import { listPatType, listPatCfg, addPlan, setPlan, saveBatchPlanSpot } from '@/api/cq/patrol'
import { SYS_PLAN, CUSTOM_PLAN, cycleTypeList } from '../utils/common'
import EditSpot from './EditPlanSpot'
// 周期类型转天数
const cycleType2days = cycleTypeList.reduce((o, i) => !void (o[i.value] = i.days) && o, {})
export default {
  components: { Treeselect, EditSpot },
  mixins: [editFormMixin],
  dicts: ['cq_patrol_plan_type'],
  data() {
    return {
      cycleTypeList,
      primaryKey: 'patPlanId',
      addApi: addPlan,
      updateApi: setPlan,
      form: {
        projectId: '',
        patPlanId: '',
        patrolTypeId: null,
        planType: 'CYCLE',
        planName: '',
        cycleCount: 1,
        cycleType: 'DAY',
        times: 1,
        daysCounts: 1,
        planBeginDate: '',
        planEndDate: '',
        remark: '',
        planSource: '3',
        status: 1
      },
      rules: {
        patrolTypeId: [{ required: true, message: '请选择巡更类型' }],
        planType: [{ required: true, message: '请选择计划类型' }],
        planName: [{ required: true, message: '请输入计划名称' }, nameRule],
        cycleType: [
          {
            validator: (rule, val, cb) => {
              if (!val) return cb('请选择重复类型')
              if (!this.form.cycleCount || !this.form.times) return cb('请输入重复次数')
              cb()
            }
          }
        ],
        daysCounts: [
          { required: true, message: '请输入完成任务天数' },
          {
            validator: (rule, val, cb) => {
              if (!this.showCycleType) return cb()

              const { cycleCount, cycleType, times } = this.form
              const days = Math.round((cycleCount * cycleType2days[cycleType]) / times)
              if (val < days) return cb(`天数不足，单次任务需约${days}天`)

              cb()
            }
          }
        ],
        planBeginDate: [
          { required: true, message: '请选择计划开始时间' },
          {
            validator: (rule, val, cb) => {
              const eTime = this.form.planEndDate
              eTime && this.$refs.form.validateField('planEndDate')
              cb()
            }
          }
        ],
        planEndDate: [
          {
            validator: (rule, val, cb) => {
              if (this.isOnce && !val) return cb('请选择计划结束时间')
              // null 设为空字符串
              if (val === null) this.form.planEndDate = ''
              const sTime = this.form.planBeginDate
              // 结束时间选填
              if (!val || !sTime) return cb()
              if (moment(sTime).isAfter(moment(val))) return cb('结束时间不能小于开始时间')
              cb()
            }
          }
        ]
      },
      patTypeLoading: false,
      patTypeTree: [],
      patCfgLoading: false
    }
  },
  computed: {
    isEdit() {
      return !!this.form.patPlanId
    },
    showCycleType() {
      return this.form.planType !== 'ONCE'
    },
    isOnce() {
      // 计划类型为一次性
      return this.form.planType === 'ONCE'
    }
  },
  methods: {
    closed() {
      this.$refs.form.resetFields()
      this.$refs.EditSpot.reset()
    },
    async opened(item = {}) {
      this.getPatTypeList()

      this.$refs.EditSpot.init({ projectId: item.projectId, patPlanId: item.patPlanId || '' })
    },
    async getPatTypeList() {
      this.patTypeLoading = true
      const res = await listPatType().catch(() => false)
      this.patTypeLoading = false
      if (res === false) return

      let data = res.data || []
      data = flatList2tree(data, { id: 'patTypeId' })
      this.patTypeTree = data
    },
    patTypeNormalizer(node) {
      if (!node.children?.length) delete node.children
      return { id: node.patTypeId, label: node.patTypeName, children: node.children }
    },
    changePlanType(val) {
      if (val === 'ONCE') {
        this.form.cycleCount = null
        this.form.cycleType = null
        this.form.times = null
        this.form.daysCounts = null
      } else {
        this.form.cycleCount = 1
        this.form.cycleType = 'DAY'
        this.form.times = 1
        this.form.daysCounts = 1
        this.$refs.form.clearValidate('planEndDate')
      }
    },
    resetCfgFields() {
      this.form.planName = ''
      this.form.cycleCount = 1
      this.form.cycleType = 'DAY'
      this.form.times = 1
      this.form.daysCounts = 1
    },
    async onChangePatrolTypeId(item) {
      this.$refs.EditSpot.clearList()
      const patrolTypeId = item.patTypeId
      if (!patrolTypeId) return this.resetCfgFields()

      const opt = { patrolTypeId, pageSize: 1, cfgType: `${SYS_PLAN},${CUSTOM_PLAN}` }
      this.patCfgLoading = true
      const res = await listPatCfg(opt).catch(() => false)
      this.patCfgLoading = false
      if (res === false) return

      const data = res.rows?.[0] || {}
      if (!data.patCfgId) return this.resetCfgFields()

      // 自动填入配置字段
      this.form.planName = data.planName
      this.form.cycleCount = data.cycleCount
      this.form.cycleType = data.cycleType
      this.form.times = data.times
      this.form.daysCounts = data.daysCounts
    },
    async addPlan() {
      const spots = this.$refs.EditSpot.getData()
      if (!spots.length) return this.msgInfo('请添加点位')

      const opt = { ...this.form }
      this.btnLoading = true
      const res = await addPlan(opt).catch(() => false)
      this.btnLoading = false
      if (res === false) return

      const patPlanId = res.data?.patPlanId
      if (!patPlanId) return this.msgError('数据返回有误，缺少计划ID')

      const opt2 = spots.map(i => ({
        projectId: opt.projectId,
        patPlanId,
        spotId: i.spotId,
        seq: i.seq || 0
      }))
      this.btnLoading = true
      const res2 = await saveBatchPlanSpot(opt2).catch(() => false)
      this.btnLoading = false
      if (res2 === false) return

      this.msgSuccess('新增成功')
      this.show = false
      this.$emit('ok')
    },
    async onSubmit() {
      const valid = await this.$refs.form.validate().catch(() => false)
      if (!valid) return

      if (!this.isEdit) return this.addPlan()

      const opt = { ...this.form }
      this.btnLoading = true
      const res = await setPlan(opt).catch(() => false)
      this.btnLoading = false
      if (res === false) return

      this.msgSuccess('提交成功')
      this.show = false
      this.$emit('ok')
    }
  }
}
</script>
